import json
from .models import ChatUser, ChatGroup, ChatMessage, UserToGroup
from .schemas import MessagesListSchemaResp
import orjson

# from channels.auth import login

from channels.generic.websocket import AsyncWebsocketConsumer

from channels.db import database_sync_to_async


class ChatConsumer(AsyncWebsocketConsumer):

    async def connect(self):
        """传入的group_id, user_id, 已经在中间价进行查询获取"""
        err: list = []
        self.user: ChatUser = self.scope["user"]
        if not self.user:
            err.append("not user")

        self.room_group: ChatGroup = self.scope["group"]
        if not self.room_group:
            err.append("not group")

        await self.accept()

        if len(err):
            await self.send(text_data=orjson.dumps({"error": ",".join(err)}).decode())
            await self.close()
        else:
            await self.send(
                text_data=orjson.dumps(
                    {
                        "message": "ok",
                        "group": {
                            "name": self.room_group.name,
                            "leader": self.room_group.leader,
                        },
                    }
                ).decode()
            )
            await self.channel_layer.group_add(self.room_group.name, self.channel_name)

    async def disconnect(self, close_code):
        """退出连接时"""
        if self.room_group.name:
            await self.channel_layer.group_discard(
                self.room_group.name, self.channel_name
            )

    async def receive(self, text_data):
        """接受客户端消息"""
        text_data_json = json.loads(text_data)

        data_message = text_data_json["message"]
        data_type = text_data_json["type"]

        # 创建消息
        if data_type == "onmessage":
            # await self.create_message(data_message)
            await self.create_message(data_message)
            await self.channel_layer.group_send(
                self.room_group.name, {"type": "chat.message", "message": data_message, "user_id": self.user.id}
            )
        # 连接成功时获取群组数据
        elif data_type == "onopen":
            await self.send(
                text_data=orjson.dumps(
                    {
                        "type": "onopen",
                        "data_list": await self.get_group_messages(),
                    }
                ).decode()
            )

    @database_sync_to_async
    def get_group_messages(self):
        """查询加入当前群组之后的全部数据"""
        user_to_group = UserToGroup.objects.only("created_at").get(group_id=self.room_group.id, user_id=self.user.id)
        messages = ChatMessage.objects.filter(group_id=self.room_group.id, created_at__gte=user_to_group.created_at)
        messages_schema = MessagesListSchemaResp(messages=messages)
        return messages_schema.model_dump()

    @database_sync_to_async
    def create_message(self, message: str):
        """新增消息"""
        ChatMessage.objects.create(
            user_id=self.user.id,
            group_id=self.room_group.id,
            sender=self.user.username,
            content=message,
        )

    async def chat_message(self, event):
        """接受消息的内容处理"""
        message = event["message"]
        user_id = event["user_id"]
        await self.send(text_data=orjson.dumps({"type": "onmessage", "message": message, "user_id": user_id}).decode())
